#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>

#define PORT 8080
#define MAX_CLIENTS 10

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr = {
        .sin_family = AF_INET,
        .sin_addr.s_addr = INADDR_ANY,
        .sin_port = htons(PORT)
    };

    bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    listen(sockfd, 5);
    printf("Select server listening on port %d...\n", PORT);

    fd_set readfds;
    int client_fds[MAX_CLIENTS] = {0};
    int max_fd = sockfd;

    while (1) {
        FD_ZERO(&readfds);
        FD_SET(sockfd, &readfds);
        for (int i = 0; i < MAX_CLIENTS; i++) {
            if (client_fds[i] > 0) FD_SET(client_fds[i], &readfds);
        }

        select(max_fd + 1, &readfds, NULL, NULL, NULL);

        if (FD_ISSET(sockfd, &readfds)) {
            int client_fd = accept(sockfd, NULL, NULL);
            for (int i = 0; i < MAX_CLIENTS; i++) {
                if (client_fds[i] == 0) {
                    client_fds[i] = client_fd;
                    max_fd = (client_fd > max_fd) ? client_fd : max_fd;
                    break;
                }
            }
        }

        for (int i = 0; i < MAX_CLIENTS; i++) {
            int fd = client_fds[i];
            if (fd > 0 && FD_ISSET(fd, &readfds)) {
                char buffer[1024];
                ssize_t n = recv(fd, buffer, sizeof(buffer), 0);
                if (n > 0) send(fd, buffer, n, 0);
                else {
                    close(fd);
                    client_fds[i] = 0;
                }
            }
        }
    }

    close(sockfd);
    return 0;
}
